package cn.bluethink.eguan.okrtask.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.bluethink.eguan.core.security.Token;
import cn.bluethink.eguan.core.service.EgFileService;
import cn.bluethink.eguan.core.service.EgResultService;
import cn.bluethink.eguan.core.service.EgUserService;
import cn.bluethink.eguan.model.core.EgFile;
import cn.bluethink.eguan.model.core.EgOType;
import cn.bluethink.eguan.model.core.EgObject;
import cn.bluethink.eguan.model.core.EgPurview;
import cn.bluethink.eguan.model.core.EgResult;
import cn.bluethink.eguan.model.core.EgRole;
import cn.bluethink.eguan.model.core.EgUser;
import cn.bluethink.eguan.model.okrtask.EgOkrTask;
import cn.bluethink.eguan.okrtask.filter.OkrTaskFilter;
import cn.bluethink.eguan.okrtask.service.EgOKRTaskService;
import cn.bluethink.eguan.result.PageInfo;
import cn.bluethink.eguan.result.ResponseMessage;
import cn.bluethink.eguan.result.ResponseResult;

/**
 * 工作任务控制器
 * 
 * @title 苏州中科蓝迪公司所有(c)2016-2021
 * @version 0.1.0
 * @describe
 * @author liuxn
 * @date 2018年10月19日 （1） liuxn于2018年10月19日创建初版本 （2）
 *       liuxn于2018年11月7日修订工作任务修改逻辑，拥有任务管理权限的用户均可修改工作任务
 *       （3）liuxn于2018年11月9日调整工作任务修改和删除逻辑，在controller中进行权限校验，
 *       如果当前登录用户为任务发布者，可修改/删除任务；否则判断当前登录用户是否拥有删除/修改任务对应权限
 *       （4）wanglei于2018年12月20日增加文件提交，删除，添加验收意见接口
 *       （5）wanglei于2019年2月13日增加获取上级目标，目标关联，目标删除接口
 */
@CrossOrigin
@RestController
@RequestMapping("/eguan/v1.0/okrtask")
public class EgOKRTaskController {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private EgOKRTaskService okrTaskService;

    @Autowired
    private EgUserService userService;

    @Autowired
    private EgFileService fileService;
    
    @Autowired
    private EgResultService resultService;

    /**
     * 创建一个OKR任务
     * 
     * @param okrTask
     * @return
     * @throws Exception
     */
    @Token(purviews = { EgPurview.OKR_TASK_MG })
    @PostMapping("/create")
    public ResponseResult<EgOkrTask> create(@RequestBody EgOkrTask okrTask) throws Exception {
        // 1、获取当前登录用户Id
        // String token = request.getHeader("Authorization");
        Long uid = (Long) request.getAttribute("userId");
        // 2、创建工作任务
        EgOkrTask result = okrTaskService.create(okrTask, uid);
        if (result != null) {
            return new ResponseResult<>(ResponseMessage.OK, result);
        }
        return new ResponseResult<>(ResponseMessage.CREATE_FAIL);
    }

    /**
     * 删除OKR任务
     * 
     * @param tid
     * @return
     * @throws Exception
     */
    @Token
    @PostMapping("/del")
    public ResponseResult<Long> del(@RequestParam Long tid) throws Exception {
        // 1、获取当前登录用户Id
        // String token = request.getHeader("Authorization");
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        // 2、如果当前用户拥有审核/工作任务权限，根据主键Id查询任务
        EgOkrTask okrtask = okrTaskService.getById(tid);
        // 3、判断该工作任务是否为空，为空，返回找不到数据
        if (okrtask == null)
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        // 获取当前登录用户当前位置权限
        EgRole role = okrTaskService.roleintask(okrtask, user);
        Long result = null;
        // 4、如果当前登录用户为任务发布者，直接删除
        if (uid.equals(okrtask.getCuser().getId())) {
            result = okrTaskService.del(uid, okrtask);
        }
        // 5、如果当前登录用户拥有信息审核/任务管理权限，直接删除
        else if (role != null && ((role.getPurview() & EgPurview.OBJECT_CHECK) > 0
                || (role.getPurview() & EgPurview.OKR_TASK_MG) > 0)) {
            result = okrTaskService.del(uid, okrtask);
        }
        // 6、否则，该用户无权限
        else {
            return new ResponseResult<>(ResponseMessage.INADEQUATE_PERMISSIONS);
        }
        // 7、删除成功/失败，返回对应信息
        if (result != null && result > 0) {
            return new ResponseResult<>(ResponseMessage.OK, result);
        }
        return new ResponseResult<>(ResponseMessage.DELETE_FAIL);
    }

    /**
     * 更新OKR任务（领取者更新任务状态）
     * 
     * @param okrTask
     * @return
     * @throws Exception
     */
    //@Token
    @PostMapping("/update")
    public ResponseResult<EgOkrTask> update(@RequestBody EgOkrTask okrTask) throws Exception {
        // 1、获取当前登录用户Id
        // String token = request.getHeader("Authorization");
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        // 2、判断是否符合工作任务更新要求，不符合返回null
        if (okrTask.getId() == 0)
            return new ResponseResult<>(ResponseMessage.NOTNULL_ID);
        // 3、验证成功，根据工作任务Id查询工作任务
        EgOkrTask oldtask = okrTaskService.getById(okrTask.getId());
        if (oldtask == null)
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        // 获取当前登录用户在该任务中的权限
        EgRole role = okrTaskService.roleintask(oldtask, user);
        // 4、工作任务获取成功，获取被指派人Id
        Long cuid = oldtask.getCuser().getId();
        Long douid = oldtask.getDouser() == null ? 0 : oldtask.getDouser().getId();
        EgOkrTask result = null;
        // 5、判断当前登录用户是否为任务发布者或者拥有任务管理权限,可修改任务基本信息
        if (cuid.equals(uid) || (role != null && (role.getPurview() & EgPurview.OKR_TASK_MG) > 0)) {
            if (okrTask.getStatus() == null || okrTask.getStatus().equals(oldtask.getStatus())) {
                // 6、更新任务基本信息（不包括任务状态）
                okrTask.setStatus(null);
                // 获取该目标的父级目标 如果该目标存在父级目标
                EgOkrTask parent = oldtask.getParent();
                if (parent != null && parent.getId() > 0) {
                    okrTask.setParent(parent);
                }
                result = okrTaskService.update(oldtask, okrTask, uid);
                if (result == null)
                    return new ResponseResult<>(ResponseMessage.UPDATE_FAIL);
                return new ResponseResult<>(ResponseMessage.OK, result);
            }
        }
        // 7、当前登录用户为任务执行人并且修改任务状态
        if (douid.equals(uid) && okrTask.getStatus() != null && !okrTask.getStatus().equals(oldtask.getStatus())) {
            // 8、如果当前用户是被指派人，更新任务状态
            EgOkrTask updateokr = new EgOkrTask(okrTask.getId(), null, null);
            updateokr.setContent(null);
            updateokr.setTags(null);
            updateokr.setStatus(okrTask.getStatus());
            result = okrTaskService.updateStatus(oldtask, updateokr, uid);
            if (result == null)
                return new ResponseResult<>(ResponseMessage.UPDATE_FAIL);
            return new ResponseResult<>(ResponseMessage.OK, result);
        }
        // 9、用户没有权限修改
        return new ResponseResult<>(ResponseMessage.INADEQUATE_PERMISSIONS);
    }

    /**
     * 获取工作任务的详细信息
     * 
     * @param tid
     * @return 返回工作任务详情（包括创建者，被指派人，任务结果，任务所在位置）
     * @throws Exception
     */
    @Token
    @GetMapping("/detail")
    public ResponseResult<EgOkrTask> detail(@RequestParam Long tid) throws Exception {
        // 1、获取工作任务详细信息
        EgOkrTask okrtask = okrTaskService.detail(tid);
        if (okrtask == null)
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        return new ResponseResult<>(ResponseMessage.OK, okrtask);
    }

    /**
     * 根据过滤条件查询OKR任务列表
     * 
     * @param filter
     * @return
     * @throws Exception
     */
    @Token(purviews = { EgPurview.OKR_TASK_MG, EgPurview.OBJECT_CHECK })
    @PostMapping("/query")
    public ResponseResult<PageInfo<EgOkrTask>> query(@RequestBody OkrTaskFilter filter) throws Exception {
        return new ResponseResult<>(ResponseMessage.OK, okrTaskService.query(filter));
    }

    /**
     * 查看工作台工作任务列表
     * 
     * @param filter
     * @return
     * @throws Exception
     */
    @Token
    @PostMapping("/myworkbench")
    public ResponseResult<PageInfo<EgOkrTask>> myworkbench(@RequestBody OkrTaskFilter filter) throws Exception {
        // 1、获取当前登录用户Id
        // String token = request.getHeader("Authorization");
        Long uid = (Long) request.getAttribute("userId");
        return new ResponseResult<>(ResponseMessage.OK, okrTaskService.myworkbench(filter, uid));
    }

    /**
     * 获取用户在当前任务中的权限
     * 
     * @param tid
     * @return
     * @throws Exception
     */
    @Token
    @GetMapping("/roleintask")
    public ResponseResult<Map<String, EgRole>> roleintask(@RequestParam Long tid) throws Exception {
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        EgOkrTask okrTask = okrTaskService.getById(tid);
        if (okrTask == null)
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        Map<String, EgRole> result = new HashMap<>();
        EgRole role = okrTaskService.roleintask(okrTask, user);
        result.put("role", role);
        return new ResponseResult<>(ResponseMessage.OK, result);
    }

    /**
     * 拖拽工作任务排序
     * 
     * @param tid
     * @param sort
     * @return
     * @throws Exception
     */
    @Token
    @PostMapping("/sort")
    public ResponseResult<Long> sort(@RequestParam Long tid, @RequestParam Integer sort) throws Exception {
        // 1、获取当前登录用户Id
        // String token = request.getHeader("Authorization");
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        // 2、如果当前用户拥有审核/工作任务权限，根据主键Id查询任务
        EgOkrTask okrtask = okrTaskService.getById(tid);
        // 3、判断该工作任务是否为空，为空，返回找不到数据
        if (okrtask == null)
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        // 获取当前登录用户当前位置权限
        EgRole role = okrTaskService.roleintask(okrtask, user);
        Long result = null;
        // 4、如果当前登录用户为任务发布者，直接删排序
        if (uid.equals(okrtask.getCuser().getId())) {
            result = okrTaskService.sort(okrtask, sort);
        }
        // 5、如果当前登录用户拥有信息审核/任务管理权限，直接排序
        else if (role != null && ((role.getPurview() & EgPurview.OBJECT_CHECK) > 0
                || (role.getPurview() & EgPurview.OKR_TASK_MG) > 0)) {
            result = okrTaskService.sort(okrtask, sort);
        }
        // 6、否则，该用户无权限
        else {
            return new ResponseResult<>(ResponseMessage.INADEQUATE_PERMISSIONS);
        }
        if (result == 0) {
            return new ResponseResult<>(ResponseMessage.UPDATE_FAIL.getStatus(), "排序失败！");
        }
        return new ResponseResult<>(ResponseMessage.OK, tid);
    }

    /**
     * 批量提交文件,支持重复提交，不覆盖
     * 
     * @param result
     * @return
     * @throws Exception
     */
    @Token
    @PostMapping("/submit")
    public ResponseResult<List<EgFile>> submit(@RequestBody EgResult result) throws Exception {
        // 针对哪个任务提交结果
        Long tid = result.getObj().getId();
        if (tid == null || tid == 0L) {
            return new ResponseResult<>(ResponseMessage.NOTNULL_CONTENT.getStatus(), "该结果所属的任务ID不能为空！");
        }
        // 获取待提交的文件列表
        List<EgFile> files = result.getFileList();
        if (files == null || files.size() == 0) {
            return new ResponseResult<>(ResponseMessage.NOTNULL_CONTENT.getStatus(), "待提交的文件列表为空！");
        }
        // 获取任务详情
        EgOkrTask okrtask = okrTaskService.detail(tid);
        if (okrtask == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        if (user == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        // 获取当前登录用户当前位置权限
        EgRole role = okrTaskService.roleintask(okrtask, user);
        if ((role != null && (role.getPurview() & EgPurview.OKR_TASK_MG) == 0)) {
            return new ResponseResult<>(ResponseMessage.INADEQUATE_PERMISSIONS);
        }
        // 创建提交的文件列表
        for (EgFile file : files) {
            if (StringUtils.isBlank(file.getFile()) || StringUtils.isBlank(file.getName())) {
                return new ResponseResult<>(ResponseMessage.NULL_REQUEST.getStatus(), "文件标识和文件名不能为空！");
            }
            file.setUploader(new EgUser(uid, null, null));
            file.setPos(new EgObject(tid, null, new EgOType(EgOType.OKR_TASK, null)));
        }
        result.setUser(new EgObject(uid, null, null));
        // 批量提交文件
        List<EgFile> submitResult = okrTaskService.submit(okrtask, result, uid);
        if (submitResult == null) {
            return new ResponseResult<>(ResponseMessage.CREATE_FAIL);
        }
        return new ResponseResult<>(ResponseMessage.OK, submitResult);
    }

    /**
     * 根据文件主键ID删除文件
     * 
     * @param fileId
     *            文件主键ID
     * @return 返回主键ID
     * @throws Exception
     */
    @Token
    @PostMapping("/delfile")
    public ResponseResult<Long> delFile(@RequestParam Long fileId) throws Exception {
        // 根据文件主键ID获取文件详情
        EgFile file = fileService.detail(fileId);
        if (file == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        // 获取文件的上传位置对象
        Long posId = file.getPos().getId();
        // 获取任务信息
        EgOkrTask okrtask = okrTaskService.detail(posId);
        if (okrtask == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        if (user == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        // 获取当前登录用户当前位置权限
        EgRole role = okrTaskService.roleintask(okrtask, user);
        // 获取该工作任务提交的结果
        EgObject okrResult = okrtask.getResult();
        EgResult subResult = null;
        if (okrResult != null && okrResult.getId() != null && okrResult.getId() > 0) {
            // 获取提交的结果详情
            subResult = resultService.detail(okrResult.getId());
        }
        Boolean result = null;
        // 如果当前登录用户具有工作任务权限，直接删除文件
        if ((role != null && (role.getPurview() & EgPurview.OKR_TASK_MG) > 0)) {
            result = okrTaskService.delFile(file, okrtask, subResult, uid);
        } else {
            return new ResponseResult<>(ResponseMessage.INADEQUATE_PERMISSIONS);
        }
        if (result != null && result) {
            return new ResponseResult<>(ResponseMessage.OK, fileId);
        }
        return new ResponseResult<>(ResponseMessage.DELETE_FAIL);
    }

    /**
     * 添加验收意见。 一般任务：有工作任务权限的人均可填写验收意见， 培训任务：只有培训老师（即创建人）可以填写验收意见。
     * 
     * @param tid
     *            任务ID
     * @param evaluate
     *            验收意见内容
     * @return
     * @throws Exception
     */
    @Token
    @PostMapping("/evaluate")
    public ResponseResult<Boolean> evaluate(@RequestParam Long tid, @RequestParam String evaluate) throws Exception {
        // 获取任务信息
        EgOkrTask okrtask = okrTaskService.getById(tid);
        if (okrtask == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        if (user == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        // 获取当前登录用户当前位置权限
        EgRole role = okrTaskService.roleintask(okrtask, user);
        if ((role != null && (role.getPurview() & EgPurview.OKR_TASK_MG) == 0)) {
            return new ResponseResult<>(ResponseMessage.INADEQUATE_PERMISSIONS);
        }
        // 设置验收意见
        okrtask.setEvaluate(evaluate);
        if (okrTaskService.update(null, okrtask, null) == null) {
            new ResponseResult<>(ResponseMessage.UPDATE_FAIL.getStatus(), "添加验收意见失败！");
        }
        return new ResponseResult<>(ResponseMessage.OK, true);
    }

    /**
     * 根据当前目标获取上级目标列表
     * 
     * @param okrTask
     * @return
     * @throws Exception
     */
    @Token
    @PostMapping("/parents")
    public ResponseResult<PageInfo<EgOkrTask>> getParents(@RequestBody EgOkrTask okrTask) throws Exception {
        return new ResponseResult<>(ResponseMessage.OK, okrTaskService.getParents(okrTask));
    }

    /**
     * 关联目标
     * 
     * @param tid
     *            当前任务ID
     * @param parentId
     *            目标任务ID
     * @return
     * @throws Exception
     */
    @Token
    @PostMapping("/relatetarget")
    public ResponseResult<EgOkrTask> relateTarget(@RequestParam Long tid, @RequestParam Long parentId)
            throws Exception {
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        // 根据工作任务Id查询工作任务
        EgOkrTask oldtask = okrTaskService.getById(tid);
        if (oldtask == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        // 获取当前登录用户在该任务中的权限
        EgRole role = okrTaskService.roleintask(oldtask, user);
        // 工作任务获取成功，获取被指派人Id
        Long cuid = oldtask.getCuser().getId();
        // 查询关联目标
        EgOkrTask parentTask = okrTaskService.getById(parentId);
        if (parentTask == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND.getStatus(), "关联的目标不存在！");
        }
        EgOkrTask result = null;
        // 判断当前登录用户是否为任务发布者或者拥有任务管理权限,可修改任务基本信息
        if (cuid.equals(uid) || (role != null && (role.getPurview() & EgPurview.OKR_TASK_MG) > 0)) {
            if (oldtask.getParent() != null && parentId.equals(oldtask.getParent().getId())) {
                EgOkrTask parent = new EgOkrTask(parentId, parentTask.getName(), null);
                parent.setTiming(parentTask.getTiming());
                oldtask.setParent(parent);
                return new ResponseResult<>(ResponseMessage.OK, oldtask);
            }
            // 更新任务基本信息(设置关联的目标)
            oldtask.setParent(new EgOkrTask(parentId, null, null));
            result = okrTaskService.update(null, oldtask, uid);
            if (result == null) {
                return new ResponseResult<>(ResponseMessage.UPDATE_FAIL);
            }
            EgOkrTask parent = new EgOkrTask(parentId, parentTask.getName(), null);
            parent.setTiming(parentTask.getTiming());
            result.setParent(parent);
            return new ResponseResult<>(ResponseMessage.OK, result);
        }
        return new ResponseResult<>(ResponseMessage.INADEQUATE_PERMISSIONS);
    }

    /**
     * 取消关联目标
     * 
     * @param tid
     *            当前任务ID
     * @param parentId
     *            被取消的目标任务ID
     * @return
     * @throws Exception
     */
    @Token
    @PostMapping("/canceltarget")
    public ResponseResult<EgOkrTask> cancelTarget(@RequestParam Long tid, @RequestParam Long parentId)
            throws Exception {
        Long uid = (Long) request.getAttribute("userId");
        EgUser user = userService.getUser(uid, false);
        // 根据工作任务Id查询工作任务
        EgOkrTask oldtask = okrTaskService.getById(tid);
        if (oldtask == null) {
            return new ResponseResult<>(ResponseMessage.DATA_NOT_FOUND);
        }
        // 获取当前登录用户在该任务中的权限
        EgRole role = okrTaskService.roleintask(oldtask, user);
        // 工作任务获取成功，获取被指派人Id
        Long cuid = oldtask.getCuser().getId();
        EgOkrTask result = null;
        // 判断当前登录用户是否为任务发布者或者拥有任务管理权限,可修改任务基本信息
        if (cuid.equals(uid) || (role != null && (role.getPurview() & EgPurview.OKR_TASK_MG) > 0)) {
            if (oldtask.getParent() != null && parentId.equals(oldtask.getParent().getId())) {
                // 更新任务基本信息（取消关联的目标，置为空）
                oldtask.setParent(null);
                result = okrTaskService.update(null, oldtask, uid);
                if (result == null) {
                    return new ResponseResult<>(ResponseMessage.UPDATE_FAIL);
                }
                return new ResponseResult<>(ResponseMessage.OK, result);
            }
        }
        return new ResponseResult<>(ResponseMessage.INADEQUATE_PERMISSIONS);
    }
}
